home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / alpha.arc / NRCMD.C < prev    next >
C/C++ Source or Header  |  1988-07-26  |  13KB  |  588 lines

  1. /* net/rom user command processing
  2.  * Dan Frank, W9NK
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9. #include "netrom.h"
  10. #include "timer.h"
  11. #include "iface.h"
  12. #include "lapb.h"
  13. #include "cmdparse.h"
  14. #include <ctype.h>
  15.  
  16. static int dointerface(), dobcnodes(), donodetimer(), donrroute(),
  17.            doobsotimer(), donodefilter() ;
  18.  
  19. static struct cmds nrcmds[] = {
  20.     "bcnodes",    dobcnodes,    2,    "netrom bcnodes <interface>", NULLCHAR,
  21.     "interface",    dointerface,    4,
  22.         "netrom interface <interface> <alias> <quality>",    NULLCHAR,
  23.     "nodefilter",    donodefilter,    0,    NULLCHAR,    NULLCHAR,
  24.     "nodetimer",    donodetimer,    0,    NULLCHAR,    NULLCHAR,
  25.     "obsotimer",    doobsotimer,    0,    NULLCHAR,    NULLCHAR,
  26.     "route",    donrroute,    0,    NULLCHAR,    NULLCHAR,
  27.     NULLCHAR,    NULLFP,        0,
  28.         "netrom subcommands: bcnodes interface nodetimer nodefilter obsotimer route",
  29.         NULLCHAR
  30. } ;
  31.  
  32. static struct timer nodetimer ;    /* timer for nodes broadcasts */
  33. static struct timer obsotimer ;    /* timer for aging routes */
  34.  
  35. /* Command multiplexer */
  36. donetrom(argc,argv)
  37. int argc ;
  38. char *argv[] ;
  39. {
  40.     return subcmd(nrcmds,argc,argv) ;
  41. }
  42.  
  43. static int dorouteadd(), doroutedrop(), doroutedump(), dorouteinfo() ;
  44.  
  45. static struct cmds routecmds[] = {
  46.     "add",    dorouteadd,    6,
  47.         "netrom route add <alias> <destination> <interface> <quality> <neighbor>",
  48.         "add failed",
  49.     "drop",    doroutedrop, 4,
  50.         "netrom route drop <destination> <neighbor> <interface>",
  51.         "drop failed",
  52.     "info", dorouteinfo, 2,
  53.         "netrom route info <destination>", NULLCHAR,
  54.     NULLCHAR,    NULLFP,    0,
  55.         "netrom route subcommands: add drop info",
  56.         NULLCHAR
  57. } ;
  58.  
  59. /* Route command multiplexer */
  60. static
  61. donrroute(argc, argv)
  62. int argc ;
  63. char *argv[] ;
  64. {
  65.     if (argc < 2) {
  66.         doroutedump() ;
  67.         return 0 ;
  68.     }
  69.     return subcmd(routecmds,argc,argv) ;
  70. }
  71.  
  72. /* Dump a list of known routes */
  73. static
  74. doroutedump()
  75. {
  76.     register struct nrroute_tab *rp ;
  77.     register int i, column ;
  78.     char buf[16] ;
  79.     char *cp ;
  80.     
  81.     column = 1 ;
  82.     
  83.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  84.         for (rp = nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next) {
  85.             strcpy(buf,rp->alias) ;
  86.             /* remove trailing spaces */
  87.             if ((cp = index(buf,' ')) == NULLCHAR)
  88.                 cp = &buf[strlen(buf)] ;
  89.             if (cp != buf)        /* don't include colon for null alias */
  90.                 *cp++ = ':' ;
  91.             pax25(cp,&rp->call) ;
  92.             printf("%-16s  ",buf) ;
  93.             if (column++ == 4) {
  94.                 printf("\n") ;
  95.                 column = 1 ;
  96.             }
  97.         }
  98.  
  99.     if (column != 1)
  100.         printf("\n") ;
  101.         
  102.     return 0 ;
  103. }
  104.  
  105. /* print detailed information on an individual route */
  106. dorouteinfo(argc,argv)
  107. int argc ;
  108. char *argv[] ;
  109. {
  110.     register struct nrroute_tab *rp ;
  111.     register struct nr_bind *bp ;
  112.     register struct nrnbr_tab *np ;
  113.     struct ax25_addr dest ;
  114.     char neighbor[60] ;
  115.  
  116.     if (setcall(&dest,argv[1]) == -1) {
  117.         printf ("bad destination name\n") ;
  118.         return -1 ;
  119.     }
  120.         
  121.     if ((rp = find_nrroute(&dest)) == NULLNRRTAB) {
  122.         printf("no such route\n") ;
  123.         return -1 ;
  124.     }
  125.  
  126.     for (bp = rp->routes ; bp != NULLNRBIND ; bp = bp->next) {
  127.         np = bp->via ;
  128.         psax25(neighbor,np->call) ;
  129.         printf("%1s %3d  %3d  %-8s  %s\n",
  130.                 (bp->flags & NRB_PERMANENT ? "P" : " "),
  131.                 bp->quality,bp->obsocnt,
  132.                 nrifaces[np->interface].interface->name,
  133.                 neighbor) ;
  134.     }
  135.     return 0 ;
  136. }
  137.         
  138. /* convert a null-terminated alias name to a blank-filled, upcased */
  139. /* version.  Return -1 on failure. */
  140. static int
  141. putalias(to,from)
  142. register char *to, *from ;
  143. {
  144.     int len, i ;
  145.     
  146.     if ((len = strlen(from)) > ALEN) {
  147.         printf ("alias too long - six characters max\n") ;
  148.         return -1 ;
  149.     }
  150.     
  151.     for (i = 0 ; i < ALEN ; i++) {
  152.         if (i < len) {
  153.             if (islower(*from))
  154.                 *to++ = toupper(*from++) ;
  155.             else
  156.                 *to++ = *from++ ;
  157.         }
  158.         else
  159.             *to++ = ' ' ;
  160.     }
  161.             
  162.     *to = '\0' ;
  163.     return 0 ;
  164. }
  165.  
  166. /* Add a route */
  167. dorouteadd(argc, argv)
  168. int argc ;
  169. char *argv[] ;
  170. {
  171.     char alias[7] ;
  172.     struct ax25_addr dest ;
  173.     unsigned quality ;
  174.     char neighbor[AXALEN * 3] ;
  175.     register int i ;
  176.     int naddr ;
  177.  
  178.     /* format alias (putalias prints error message if necessary) */
  179.     if (putalias(alias,argv[1]) == -1)
  180.         return -1 ;
  181.  
  182.     /* format destination callsign */
  183.     if (setcall(&dest,argv[2]) == -1) {
  184.         printf("bad destination callsign\n") ;
  185.         return -1 ;
  186.     }
  187.  
  188.     /* find interface */
  189.     for (i = 0 ; i < nr_numiface ; i++)
  190.         if (!strcmp(nrifaces[i].interface->name,argv[3]))
  191.             break ;
  192.     if (i == nr_numiface) {
  193.         printf("Interface \"%s\" not found\n",argv[3]) ;
  194.         return -1 ;
  195.     }
  196.     
  197.     /* get and check quality value */
  198.     if ((quality = atoi(argv[4])) > 255) {
  199.         printf("maximum route quality is 255\n") ;
  200.         return -1 ;
  201.     }
  202.  
  203.     /* make sure no more than 2 digis */
  204.     naddr = argc - 5 ;
  205.     if (naddr > 3) {
  206.         printf("no more than 2 digipeaters for a net/rom neighbor\n") ;
  207.         return -1 ;
  208.     }
  209.     
  210.     /* format neighbor address string */
  211.     setpath(neighbor,&argv[5],naddr) ;
  212.  
  213.     return nr_routeadd(alias,&dest,i,quality,neighbor,1) ;
  214. }
  215.  
  216.  
  217. /* drop a route */
  218. static
  219. doroutedrop(argc,argv)
  220. int argc ;
  221. char *argv[] ;
  222. {
  223.     struct ax25_addr dest, neighbor ;
  224.     register int i ;
  225.  
  226.     /* format destination and neighbor callsigns */
  227.     if (setcall(&dest,argv[1]) == -1) {
  228.         printf("bad destination callsign\n") ;
  229.         return -1 ;
  230.     }
  231.     if (setcall(&neighbor,argv[2]) == -1) {
  232.         printf("bad neighbor callsign\n") ;
  233.         return -1 ;
  234.     }
  235.  
  236.     /* find interface */
  237.     for (i = 0 ; i < nr_numiface ; i++)
  238.         if (!strcmp(nrifaces[i].interface->name,argv[3]))
  239.             break ;
  240.     if (i == nr_numiface) {
  241.         printf("Interface \"%s\" not found\n",argv[3]) ;
  242.         return -1 ;
  243.     }
  244.  
  245.     return nr_routedrop(&dest,&neighbor,i) ;
  246. }
  247.     
  248.     
  249. /* make an interface available to net/rom */
  250. int
  251. dointerface(argc,argv)
  252. int argc ;
  253. char *argv[] ;
  254. {
  255.     register char *sp, *dp ;
  256.     int i, len ;
  257.     register struct interface *ifp ;
  258.     extern struct interface *ifaces ;
  259.  
  260.     if (nr_interface == NULLIF) {
  261.         printf("Attach netrom interface first\n") ;
  262.         return 1 ;
  263.     }
  264.     
  265.     if (nr_numiface >= NRNUMIFACE) {
  266.         printf("Only %d net/rom interfaces available\n",NRNUMIFACE) ;
  267.         return 1 ;
  268.     }
  269.     
  270.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  271.         if(strcmp(argv[1],ifp->name) == 0)
  272.             break;
  273.     }
  274.     if(ifp == NULLIF){
  275.         printf("Interface \"%s\" unknown\n",argv[1]);
  276.         return 1;
  277.     }
  278.     for (i = 0 ; i < nr_numiface ; i++)
  279.         if (nrifaces[i].interface == ifp) {
  280.             printf("Interface \"%s\" is already registered\n",argv[1]) ;
  281.             return 1 ;
  282.         }
  283.         
  284.     nrifaces[nr_numiface].interface = ifp ;
  285.  
  286.     if (putalias(nrifaces[nr_numiface].alias,argv[2]) == -1)
  287.         return 1 ;
  288.         
  289.     if ((nrifaces[nr_numiface].quality = atoi(argv[3])) > 255) {
  290.         printf("Quality cannot be greater than 255\n") ;
  291.         return 1 ;
  292.     }
  293.         
  294.     nr_numiface++ ;            /* accept this interface */
  295.     return 0 ;
  296. }
  297.  
  298. /* Broadcast nodes list on named interface. */
  299.  
  300. int
  301. dobcnodes(argc,argv)
  302. int argc ;
  303. char *argv[] ;
  304. {
  305.     register int i ;
  306.     for (i = 0 ; i < nr_numiface ; i++)
  307.         if (!strcmp(nrifaces[i].interface->name,argv[1]))
  308.             break ;
  309.     if (i == nr_numiface) {
  310.         printf("Interface \"%s\" not found\n",argv[1]) ;
  311.         return 1 ;
  312.     }
  313.         
  314.     nr_bcnodes(i) ;
  315. }
  316.  
  317. #define TICKSPERSEC    (1000 / MSPTICK)    /* Ticks per second */
  318.  
  319. /* Set outbound node broadcast interval */
  320. static int
  321. donodetimer(argc,argv)
  322. int argc;
  323. char *argv[];
  324. {
  325.     int donodetick();
  326.  
  327.     if(argc < 2){
  328.         printf("%d/%d\n",(nodetimer.start - nodetimer.count)/TICKSPERSEC,
  329.         nodetimer.start/TICKSPERSEC);
  330.         return 0;
  331.     }
  332.     stop_timer(&nodetimer) ;    /* in case it's already running */
  333.     nodetimer.func = (void (*)())donodetick;/* what to call on timeout */
  334.     nodetimer.arg = NULLCHAR;        /* dummy value */
  335.     nodetimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  336.     start_timer(&nodetimer);        /* and fire it up */
  337.     return 0;
  338. }
  339.  
  340. static int
  341. donodetick()
  342. {
  343.     register int i ;
  344.  
  345.     for (i = 0 ; i < nr_numiface ; i++)
  346.         nr_bcnodes(i) ;
  347.  
  348.     /* Restart timer */
  349.     start_timer(&nodetimer) ;
  350. }
  351.  
  352. /* Set timer for aging routes */
  353. static int
  354. doobsotimer(argc,argv)
  355. int argc;
  356. char *argv[];
  357. {
  358.     extern int doobsotick();
  359.  
  360.     if(argc < 2){
  361.         printf("%d/%d\n",(obsotimer.start - obsotimer.count)/TICKSPERSEC,
  362.         obsotimer.start/TICKSPERSEC);
  363.         return 0;
  364.     }
  365.     stop_timer(&obsotimer) ;    /* just in case it's already running */
  366.     obsotimer.func = (void (*)())doobsotick;/* what to call on timeout */
  367.     obsotimer.arg = NULLCHAR;        /* dummy value */
  368.     obsotimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  369.     start_timer(&obsotimer);        /* and fire it up */
  370.     return 0;
  371. }
  372.  
  373.  
  374. /* Go through the routing table, reducing the obsolescence count of
  375.  * non-permanent routes, and purging them if the count reaches 0
  376.  */
  377. static int
  378. doobsotick()
  379. {
  380.     register struct nrnbr_tab *np ;
  381.     register struct nrroute_tab *rp, *rpnext ;
  382.     register struct nr_bind *bp, *bpnext ;
  383.     struct ax25_addr neighbor ;
  384.     int i ;
  385.  
  386.     for (i = 0 ; i < NRNUMCHAINS ; i++) {
  387.         for (rp = nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rpnext) {
  388.             rpnext = rp->next ;     /* save in case we free this route */
  389.             for (bp = rp->routes ; bp != NULLNRBIND ; bp = bpnext) {
  390.                 bpnext = bp->next ;    /* in case we free this binding */
  391.                 if (bp->flags & NRB_PERMANENT)    /* don't age these */
  392.                     continue ;
  393.                 if (--bp->obsocnt == 0) {        /* time's up! */
  394.                     if (bp->next != NULLNRBIND)
  395.                         bp->next->prev = bp->prev ;
  396.                     if (bp->prev != NULLNRBIND)
  397.                         bp->prev->next = bp->next ;
  398.                     else
  399.                         rp->routes = bp->next ;
  400.                     rp->num_routes-- ;            /* one less binding */
  401.                     np = bp->via ;                /* find the neighbor */
  402.                     free(bp) ;                    /* now we can free the bind */
  403.                     /* Check to see if we can free the neighbor */
  404.                     if (--np->refcnt == 0) {
  405.                         if (np->next != NULLNTAB)
  406.                             np->next->prev = np->prev ;
  407.                         if (np->prev != NULLNTAB)
  408.                             np->prev->next = np->next ;
  409.                         else {
  410.                             memcpy(neighbor.call,np->call,ALEN) ;
  411.                             neighbor.ssid = np->call[ALEN] ;
  412.                             nrnbr_tab[nrhash(&neighbor)] = np->next ;
  413.                         }
  414.                         free(np) ;    /* free the storage */
  415.                     }
  416.                 }
  417.             }
  418.             if (rp->num_routes == 0) {        /* did we free them all? */
  419.                 if (rp->next != NULLNRRTAB)
  420.                     rp->next->prev = rp->prev ;
  421.                 if (rp->prev != NULLNRRTAB)
  422.                     rp->prev->next = rp->next ;
  423.                 else
  424.                     nrroute_tab[i] = rp->next ;
  425.  
  426.                 free(rp) ;
  427.             }
  428.         }
  429.     }
  430.  
  431.     start_timer(&obsotimer) ;
  432. }
  433.  
  434.  
  435. static int donfadd(), donfdrop(), donfmode() ;
  436.  
  437. static struct cmds nfcmds[] = {
  438.     "add",    donfadd,    3,
  439.         "netrom nodefilter add <neighbor> <interface>",
  440.         "add failed",
  441.     "drop",    donfdrop,    3,
  442.         "netrom nodefilter drop <neighbor> <interface>",
  443.         "drop failed",
  444.     "mode",    donfmode,    0,    NULLCHAR,    NULLCHAR,
  445.     NULLCHAR,    NULLFP,    0,
  446.         "nodefilter subcommands: add drop mode",
  447.         NULLCHAR
  448. } ;
  449.  
  450. /* nodefilter command multiplexer */
  451. static
  452. donodefilter(argc,argv)
  453. int argc ;
  454. char *argv[] ;
  455. {
  456.     if (argc < 2) {
  457.         donfdump() ;
  458.         return 0 ;
  459.     }
  460.     return subcmd(nfcmds,argc,argv) ;
  461. }
  462.  
  463. /* display a list of <callsign,interface> pairs from the filter
  464.  * list.
  465.  */
  466. static
  467. donfdump()
  468. {
  469.     int i, column = 1 ;
  470.     struct nrnf_tab *fp ;
  471.     char buf[16] ;
  472.  
  473.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  474.         for (fp = nrnf_tab[i] ; fp != NULLNRNFTAB ; fp = fp->next) {
  475.             pax25(buf,&fp->neighbor) ;
  476.             printf("%-7s %-8s  ",
  477.                     buf,nrifaces[fp->interface].interface->name) ;
  478.             if (column++ == 4) {
  479.                 printf("\n") ;
  480.                 column = 1 ;
  481.             }
  482.         }
  483.  
  484.     if (column != 1)
  485.         printf("\n") ;
  486.  
  487.     return 0 ;
  488. }
  489.  
  490. /* add an entry to the filter table */
  491. static
  492. donfadd(argc,argv)
  493. int argc ;
  494. char *argv[] ;
  495. {
  496.     struct ax25_addr neighbor ;
  497.     register int i ;
  498.  
  499.     /* format callsign */
  500.     if (setcall(&neighbor,argv[1]) == -1) {
  501.         printf("bad neighbor callsign\n") ;
  502.         return -1 ;
  503.     }
  504.  
  505.     /* find interface */
  506.     for (i = 0 ; i < nr_numiface ; i++)
  507.         if (!strcmp(nrifaces[i].interface->name,argv[2]))
  508.             break ;
  509.     if (i == nr_numiface) {
  510.         printf("Interface \"%s\" not found\n",argv[2]) ;
  511.         return -1 ;
  512.     }
  513.  
  514.     return nr_nfadd(&neighbor,i) ;
  515. }
  516.  
  517. /* drop an entry from the filter table */
  518. static
  519. donfdrop(argc,argv)
  520. int argc ;
  521. char *argv[] ;
  522. {
  523.     struct ax25_addr neighbor ;
  524.     register int i ;
  525.  
  526.     /* format neighbor callsign */
  527.     if (setcall(&neighbor,argv[1]) == -1) {
  528.         printf("bad neighbor callsign\n") ;
  529.         return -1 ;
  530.     }
  531.  
  532.     /* find interface */
  533.     for (i = 0 ; i < nr_numiface ; i++)
  534.         if (!strcmp(nrifaces[i].interface->name,argv[2]))
  535.             break ;
  536.     if (i == nr_numiface) {
  537.         printf("Interface \"%s\" not found\n",argv[2]) ;
  538.         return -1 ;
  539.     }
  540.  
  541.     return nr_nfdrop(&neighbor,i) ;
  542. }
  543.  
  544. /* nodefilter mode subcommand */
  545. static
  546. donfmode(argc,argv)
  547. int argc ;
  548. char *argv[] ;
  549. {
  550.     if (argc < 2) {
  551.         printf("filter mode is ") ;
  552.         switch (nr_nfmode) {
  553.             case NRNF_NOFILTER:
  554.                 printf("none\n") ;
  555.                 break ;
  556.             case NRNF_ACCEPT:
  557.                 printf("accept\n") ;
  558.                 break ;
  559.             case NRNF_REJECT:
  560.                 printf("reject\n") ;
  561.                 break ;
  562.             default:
  563.                 printf("some strange, unknown value\n") ;
  564.         }
  565.         return 0 ;
  566.     }
  567.     
  568.     switch (argv[1][0]) {
  569.         case 'n':
  570.         case 'N':
  571.             nr_nfmode = NRNF_NOFILTER ;
  572.             break ;
  573.         case 'a':
  574.         case 'A':
  575.             nr_nfmode = NRNF_ACCEPT ;
  576.             break ;
  577.         case 'r':
  578.         case 'R':
  579.             nr_nfmode = NRNF_REJECT ;
  580.             break ;
  581.         default:
  582.             printf("modes are: none accept reject\n") ;
  583.             return -1 ;
  584.     }
  585.  
  586.     return 0 ;
  587. }
  588.